<?php

require_once('Zend/Db/Table/Row/Abstract.php');

class Core_User extends Zend_Db_Table_Row_Abstract
{

	// ============================ SESSION NAMESPACE ============================

	/**
	 * Namespace variable for user related session variables.
	 *
	 * @var string
	 */
	const SESSION_NAMESPACE = 'CORE_NAMESPACE_USER';

	// ============================ USER ROLES ============================
	/**
	* Role descriptor for the default user, also known as a guest.
	*
	* @var string
	*/
	const ROLE_GUEST = 'guest';

	/**
	 * Role constant for a user who may have registered, but whose credentials
	 * are in some way in an incomplete or unverified state. This is useful if you
	 * need to have a user fill out additional information before proceeding with
	 * the functionality of your app.
	 *
	 * @var string
	 */
	const ROLE_PENDING = 'pending';

	/**
	 * A basic, run of the mill registered user who has general access to the features
	 * on this site.
	 *
	 * @var string
	 */
	const ROLE_USER = 'user';

	/**
	 * An administrator on the site, who has general administrative rights.
	 *
	 * @var string
	 */
	const ROLE_ADMIN = 'admin';

	/**
	 * A super admin, generally described as an individual who has dangerous levels of
	 * rights within the system. We generally recommend that you do NOT implement
	 * this security level because of the threat of hacking, however it's here if you
	 * need it.
	 *
	 * @var string
	 */
	const ROLE_SUPERADMIN = 'superadmin';


	// ============================ SPECIAL USERS ============================
	/**
	* Role descriptor for the crontab user. We recommend we assign rights
	* to this role seperately of the normal inheritance tree.
	*
	* @var string
	*/
	const ROLE_CRON = 'cron';

	/**
	 * Private static reference to the user table.
	 *
	 * @return Zend_Db_Table
	 */
	private static $table;

	/**
	 * Name of the class of the Zend_Db_Table_Abstract object.
	 *
	 * @var string
	 */
	protected $_tableClass = 'Zend_Db_Table';

	/**
	 * Select access method, for slightly more complex queries.
	 *
	 * @return Zend_Db_Table_Select
	 */
	public static function getTableInstance()
	{
		if ( empty(Core_User::$table ) )
		{
			Core_User::$table = new Zend_Db_Table('user');
			Core_User::$table->setRowClass('Core_User');
		}
			
		return Core_User::$table;
	}

	/**
	 * Factory Method. Spits out a user object that's tied to the database.
	 *
	 * @return Core_User
	 */
	public static function factory( $id_or_email  = null)
	{
		$table = Core_User::getTableInstance();
			
		if ( is_null($id_or_email) )
		{
			$row = $table->createRow(array(), Zend_Db_Table_Abstract::DEFAULT_DB);
		}
		else if ( is_int($id_or_email) )
		{
			$row = $table->fetchRow( $table->select()->where('userId=?',$id_or_email));
		}
		else
		{
			$row = $table->fetchRow( $table->select()->where('email=?',$id_or_email));
		}
			
		return $row;
	}

	/**
	 * This helper sets the current user into the session.
	 *
	 * @param $user Core_User
	 * @return Core_User
	 */
	public static function setCurrentUser( $user )
	{
		$userNamespace = new Zend_Session_Namespace ( self::SESSION_NAMESPACE );

		if ( is_null($user) )
		{
			unset($userNamespace->user);
		}
		else
		{
			// Save the user
			$userNamespace->user = $user;
		}

		return $user;
	}

	/**
	 * This helper retrieves the current user.
	 *
	 * @return Core_User
	 */
	public static function getCurrentUser()
	{
		// Store the user in the session
		$userNamespace = new Zend_Session_Namespace ( self::SESSION_NAMESPACE );

		$user = $userNamespace->user;
		
		if ( !empty($user) && !$user->isConnected() )
		{
			$user->setTable(self::getTableInstance());
		}

		return $user;
	}


	/**
	 * Sets the password on this user.
	 *
	 * @param string $password
	 */
	private function setPassword( $password )
	{
		// Encrypt the password
		$salt = substr( md5(rand()), 0, 10 );
		$encrypted = sha1( $password . $salt );

		$saltName = $this->_transformColumn('salt');
		$passwordName = $this->_transformColumn('password');

		$this->_data[$saltName] = $salt;
		$this->_modifiedFields[$saltName] = true;

		$this->_data[$passwordName] = $encrypted;
		$this->_modifiedFields[$passwordName] = true;
	}

	/**
	 * @inheritDoc
	 */
	protected function _doInsert()
	{
		$this->created = new Zend_Db_Expr('NOW()');
		$this->updated = new Zend_Db_Expr('NOW()');
			
		parent::_doInsert();
	}

	/**
	 * @inheritDoc
	 */
	protected function _doUpdate()
	{
		$this->updated = new Zend_Db_Expr('NOW()');
			
		parent::_doUpdate();
	}

	/**
	 * Set row field value
	 *
	 * @param  string $columnName The column key.
	 * @param  mixed  $value      The value for the property.
	 * @return void
	 * @throws Zend_Db_Table_Row_Exception
	 */
	public function __set($columnName, $value)
	{
		if ( $columnName == 'password' )
		{
			$this->setPassword($value);
		}
		else
		{
			parent::__set($columnName, $value);
		}
	}
}